package models

import (
	"database/sql"
	"fmt"
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

// User 模型结构体
type User struct {
	gorm.Model
	Name string
	Age  int
}

// 连接数据库
func ConnectDB(username string, password string, host string, port string, database string) (*gorm.DB, error) {
	dsn := username + ":" + password + "@tcp(" + host + ":" + port + ")" + "/" + database + "?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		return nil, fmt.Errorf("无法连接数据库: %s", err)
	}
	return db, nil
}

// 创建记录
func CreateUser(db *gorm.DB, user *User) error {
	result := db.Create(user)
	if result.Error != nil {
		return fmt.Errorf("创建记录失败: %s", result.Error)
	}
	return nil
}

// 查询记录
func GetUser(db *gorm.DB, userID uint) (*User, error) {
	var user User
	result := db.First(&user, userID)
	if result.Error != nil {
		return nil, fmt.Errorf("查询记录失败: %s", result.Error)
	}
	return &user, nil
}

// 更新记录
func UpdateUser(db *gorm.DB, user *User, updates map[string]interface{}) error {
	result := db.Model(user).Updates(updates)
	if result.Error != nil {
		return fmt.Errorf("更新记录失败: %s", result.Error)
	}
	return nil
}

// 删除记录
func DeleteUser(db *gorm.DB, user *User) error {
	result := db.Delete(user)
	if result.Error != nil {
		return fmt.Errorf("删除记录失败: %s", result.Error)
	}
	return nil
}

// 执行自定义 SQL 查询
func ExecuteCustomSQL(db *gorm.DB, query string, args ...interface{}) (*sql.Rows, error) {
	rows, err := db.Raw(query, args...).Rows()
	if err != nil {
		return nil, fmt.Errorf("执行自定义 SQL 查询失败: %s", err)
	}
	return rows, nil
}

// 从源数据库读取数据并写入目标数据库
func MigrateData(sourceDB *sql.DB, targetDB *gorm.DB) error {
	// 从源数据库读取数据
	rows, err := sourceDB.Query("SELECT * FROM users")
	if err != nil {
		return fmt.Errorf("读取源数据库数据失败: %s", err)
	}
	defer rows.Close()

	// 逐行处理数据并写入目标数据库
	for rows.Next() {
		var user User
		err := rows.Scan(&user.ID, &user.Name, &user.Age)
		if err != nil {
			return fmt.Errorf("扫描源数据库数据失败: %s", err)
		}

		// 写入目标数据库
		err = targetDB.Create(&user).Error
		if err != nil {
			return fmt.Errorf("写入目标数据库失败: %s", err)
		}
	}

	// 检查遍历过程中是否有错误
	if err := rows.Err(); err != nil {
		return fmt.Errorf("遍历源数据库数据失败: %s", err)
	}

	return nil
}
